package nl.runnable.solr.xslt;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Value Object representing the qualified name of an XML element.
 * <p>
 * Used internally by {@link DefaultTemplatesResolver} as a lookup key, hence this class implements {@link #hashCode()}
 * and {@link #equals(Object)}.
 * 
 * @author Laurens Fridael
 * 
 */
public class QualifiedName {

	private final String localName;

	private final String namespaceUri;

	public static QualifiedName fromString(final String value) {
		final Matcher matcher = Pattern.compile("\\{(.+?)\\}(.+)").matcher(value);
		if (matcher.matches() == false) {
			return new QualifiedName(value, null);
		} else {
			return new QualifiedName(matcher.group(2), matcher.group(1));
		}
	}

	public static QualifiedName fromLocalName(final String localName) {
		return new QualifiedName(localName, null);
	}

	public QualifiedName(final String localName, final String namespaceUri) {
		if (localName == null) {
			throw new IllegalArgumentException("Local name cannot be null.");
		}
		this.localName = localName;
		this.namespaceUri = namespaceUri;
	}

	public String getLocalName() {
		return localName;
	}

	public String getNamespaceUri() {
		return namespaceUri;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((localName == null) ? 0 : localName.hashCode());
		result = prime * result + ((namespaceUri == null) ? 0 : namespaceUri.hashCode());
		return result;
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final QualifiedName other = (QualifiedName) obj;
		if (localName == null) {
			if (other.localName != null) {
				return false;
			}
		} else if (!localName.equals(other.localName)) {
			return false;
		}
		if (namespaceUri == null) {
			if (other.namespaceUri != null) {
				return false;
			}
		} else if (!namespaceUri.equals(other.namespaceUri)) {
			return false;
		}
		return true;
	}

	/**
	 * Returns the String representation in the format <code>{namespaceUri}localName</code>.
	 * 
	 * @return
	 */
	@Override
	public String toString() {
		if (namespaceUri != null) {
			return String.format("{%s}%s", namespaceUri, localName);
		} else {
			return localName;
		}
	}

}
